身為 Java 開發者的你有沒有過一種感覺,感覺 Java 語法有點囉嗦?滿山滿谷的 getter、setter 大同小異卻又不能沒有它們,雖然 IDE 能幫你快速產出這類程式碼,但它們還是在,臃腫的你我心煩。
Lombok 正是為此存在,它是一個 Java 函式庫,通過使用其提供的註解 (Annotation) 讓我們省略一些常用、重複性高的程式碼。Lombok 是種語法糖,並沒有改變 Java 的本質,它只是告訴 IDE:「別這麼死板,就當那些不存在的 code 已經寫過了。」,然後 Lombok 會在編譯時幫你補上。
加入 Maven 依賴。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
安裝 Lombok plugin 到 Eclipse,有兩種做法:
jar 檔
Maven 下載好套件後,到 .m2
下的 Lombok 目錄下雙擊執行 lombok.jar
打開安裝程式。安裝程式會自動找到 Eclipse 的位置,只要照指示安裝就好。
lombok.jar
也可以到 https://projectlombok.org/download 下載,檔案一樣。
Eclipse 內建 plugin installer
打開 Eclipse 點 Help > Install New Software...
在 Work with:
欄位輸入 https://projectlombok.org/p2
,執行安裝。
本文只介紹常用的幾個功能,想瞭解完整功能請到 https://projectlombok.org/features/
boolean
,用 @Getter
會產生 is
開頭的方法,例如: isEnabled()
。public
,可以用 AccessLevel
修改成: PUBLIC
、PROTECTED
、PACKAGE
、PRIVATE
或 NONE
。Java + Lombok
@Getter
@Setter(AccessLevel.PROTECTED)
public class Example {
private String name;
private boolean enabled;
}
Java
public class Example {
private String name;
private boolean enabled;
public String getName() {
return this.name;
}
protected void setName(final String name) {
this.name = name;
}
public boolean isEnabled() {
return this.enabled;
}
protected void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
}
toString()
。toString()
預設印出所有非 static
的 field。@ToString.Exclude
排除不想印出的 field。@ToString(onlyExplicitlyIncluded = true)
改成預設不印出任何 field,然後用 @ToString.Include
加入想印出的 field。@ToString(callSuper = true)
,一併呼叫父類別的 toString()
印出。Java + Lombok
@ToString
public class Example {
private Integer age;
private String name;
@ToString.Exclude
private boolean enabled;
}
Java
public class Example {
private Integer age;
private String name;
private boolean enabled;
@Override
public String toString() {
return "Example(age=" + this.age + ", name=" + this.name + ")";
}
}
equals(Object other)
與 hashCode()
。static
與 transient
的 field。@EqualsAndHashCode.Exclude
排除不想比對的 field。@EqualsAndHashCode(onlyExplicitlyIncluded = true)
改成預設不比對任何 field,然後用 @EqualsAndHashCode.Include
加入想比對的 field。equals
和 hashCode
。 可設定 @EqualsAndHashCode(callSuper = true)
一併呼叫父類別的 equals
與 hashCode
進行比對。Java + Lombok
@EqualsAndHashCode
public class Example {
private Integer age;
private String name;
@EqualsAndHashCode.Exclude
private boolean enabled;
public String getName() {
return this.name;
}
}
Java
public class Example {
private Integer age;
private String name;
private boolean enabled;
public String getName() {
return this.name;
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof Example)) return false;
final Example other = (Example) o;
if (!other.canEqual((Object) this)) return false;
if (this.age == null ? other.age != null : !this.age.equals(other.age)) return false;
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
return true;
}
protected boolean canEqual(final Object other) {
return other instanceof Example;
}
@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + (this.age == null ? 43 : this.age.hashCode());
result = result * PRIME + (this.getName() == null ? 43 : this.getName().hashCode());
return result;
}
}
@NonNull
在 field 上,Lombok 會加入 null check 到由 Lombok 建立的相關方法或建構子。@NonNull
在方法或建構子的參數上,Lombok 會建立 null check 到方法 / 建構子。this()
、super()
之後,其它程式碼之前。NullPointerException
。Java + Lombok
public class Example {
private String name;
public Example(@NonNull Person person) {
super();
this.name = person.getName();
}
}
Java
public class Example {
private String name;
public Example(@NonNull Person person) {
super();
if (person == null) {
throw new NullPointerException("person is marked non-null but is null");
}
this.name = person.getName();
}
}
@NoArgsConstructor
在類別上,Lombok 會建立沒有參數的建構子,要注意:
@NoArgsConstructor
)。final
且沒預設值的 field 時 IDE 會報錯,如果你不想宣告預設值,可以用 @NoArgsConstructor(force = true)
,讓建構子把這些 field 設成 0
/ false
/ null
。@RequiredArgsConstructor
在類別上,Lombok 會建立參數為待處理 field 的建構子。待處理 field 是指沒預設值,且宣告為 final
或標註 @NonNull
的 field。@AllArgsConstructor
在類別上,Lombok 會建立參數為所有 field 的建構子。Java + Lombok
@NoArgsConstructor(force = true)
@RequiredArgsConstructor
@AllArgsConstructor
public class Example {
private String name;
private final boolean enabled;
}
Java
public class Example {
private String name;
private final boolean enabled;
public Example() {
this.enabled = false;
}
public Example(final boolean enabled) {
this.enabled = enabled;
}
public Example(final String name, final boolean enabled) {
this.name = name;
this.enabled = enabled;
}
}
@Data
在類別上,等於同時標註了:
@Getter
@Setter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
@Data
內沒有包含 @NoArgsConstructor
,再次提醒,最好加上。@Data
內含的 annotation 都是預設值,如果想要改設定,請另外加上要改的標籤與參數。Java + Lombok
@Data
public class ExampleData {
private String name;
private final boolean enabled;
}
Java
public class Example {
private String name;
private final boolean enabled;
public Example(final boolean enabled) {
this.enabled = enabled;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public boolean isEnabled() {
return this.enabled;
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof Example)) return false;
final Example other = (Example) o;
if (!other.canEqual((Object) this)) return false;
if (this.isEnabled() != other.isEnabled()) return false;
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
return true;
}
protected boolean canEqual(final Object other) {
return other instanceof Example;
}
@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + (this.isEnabled() ? 79 : 97);
result = result * PRIME + (this.getName() == null ? 43 : this.getName().hashCode());
return result;
}
@Override
public String toString() {
return "Example(name=" + this.getName() + ", enabled=" + this.isEnabled() + ")";
}
}
@Log
在類別上,Lombok 會建立一個 log 的 static final
常數。@Log
、@Log4j2
、@Slf4j
。Java + Lombok
@Log4j2
public class Example {
}
Java
public class Example {
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(Example.class);
}
Delombok 是 Lombok 內建的工具,能把含 Lombok 的 Java 程式碼輸出成純 Java 程式碼,對於讓我們了解 Lombok 做了什麼很有幫助。
輸出成檔案
使用 CLI 對 .m2
下的 lombok.jar
執行以下指令:
{src}
- 含 Lombok 的 Java 檔案目錄。
{src-delomboked}
- 輸出純 Java 檔案目錄。
java -jar lombok.jar delombok {src} -d {src-delomboked}
輸出到 console
使用 CLI 對 .m2
下的 lombok.jar
執行以下指令:
{MyJavaFile.java}
- 含 Lombok 的 Java 檔案路徑。
java -jar lombok.jar delombok -p {MyJavaFile.java}